home *** CD-ROM | disk | FTP | other *** search
- /*
- * bdy.c
- * author: Celeste Fowler
- * date: June 12, 1992
- */
-
- #include <stdlib.h>
- #include "geom.h"
- #include "polylistP.h"
- #include "ooglutil.h"
- #include "plutil.h"
- #include "bdy.h"
-
-
- #define min(a, b) ((a < b) ? a : b)
- #define max(a, b) ((a > b) ? a : b)
-
- static char msg[] = "bdy.c";
-
- /* Precision. The global declaration is a hack to get the value out
- * of Bdy and into EdgeCmp where it is needed (EdgeCmp must be called by
- * qsort. */
- static float precision;
-
- int EdgeCmp(HPoint3 **a, HPoint3 **b)
- {
- int i;
- char *chara, *charb;
- float dist00, dist01, dist11, dist10;
-
- while (1) {
- dist00 = HPt3Distance(a[0], b[0]);
- dist01 = HPt3Distance(a[0], b[1]);
- dist11 = HPt3Distance(a[1], b[1]);
- dist10 = HPt3Distance(a[1], b[0]);
-
- if (dist00 > precision && dist01 > precision) break;
- if (dist11 > precision && dist10 > precision) break;
- if (dist00 < precision && dist11 > precision) break;
- if (dist01 < precision && dist10 > precision) break;
- if (dist11 < precision && dist00 > precision) break;
- if (dist10 < precision && dist01 > precision) break;
- return 0;
- }
-
- chara = (char *)a[0];
- charb = (char *)b[0];
- for (i = 0; i < sizeof(HPoint3); i++)
- if (chara[i] != charb[i]) return chara[i] - charb[i];
- chara = (char *)a[1];
- charb = (char *)b[1];
- for (i = 0; i < sizeof(HPoint3); i++)
- if (chara[i] != charb[i]) return chara[i] - charb[i];
-
- }
-
- Geom *Bdy(Geom *g, float prec) {
- int i, j, k;
-
- PolyList *p;
- int n_edges;
- HPoint3 **edges;
-
- Geom *vect;
- short *vcounts, *ccounts;
- Point3 *verts;
- ColorA color;
-
- g = (Geom *)AnyToPL(g, TM_IDENTITY);
- if (g == NULL) return NULL;
-
- precision = prec;
-
- /* Get a consolidated version of the polylist. */
- p = (PolyList *)PLConsol(g, 0.0);
- GeomDelete(g);
-
- /* Count the number of edges in the polygon */
- for (i = n_edges = 0; i < p->n_polys; i++) n_edges += p->p[i].n_vertices;
-
- /* Put the edges in an array and sort it */
- edges = OOGLNewNE(HPoint3 *, 2 * n_edges, msg);
- for (i = k = 0; i < p->n_polys; i++) {
- for (j = 0; j < p->p[i].n_vertices; j++) {
- edges[k * 2] = (HPoint3 *)
- min(p->p[i].v[j], p->p[i].v[(j + 1) % p->p[i].n_vertices]);
- edges[k * 2 + 1] = (HPoint3 *)
- max(p->p[i].v[j], p->p[i].v[(j + 1) % p->p[i].n_vertices]);
- k++;
- }
- if (p->p[i].n_vertices == 2) k--;
- }
- n_edges = k;
- precision = 0.0;
- qsort(edges, n_edges, 2 * sizeof(HPoint3 *), (int (*)())EdgeCmp);
- precision = prec;
-
- /* Eliminate everything mentioned more than once */
- for (i = j = k = 0; i < n_edges; i++)
- if (EdgeCmp(&edges[i*2], &edges[k*2])) {
- if (i == k + 1) {
- edges[j*2] = edges[k*2];
- edges[j*2 + 1] = edges[k*2 + 1];
- j++;
- }
- k = i;
- }
- if (i == k + 1) {
- edges[j*2] = edges[k*2];
- edges[j*2 + 1] = edges[k*2 + 1];
- j++;
- }
- if (!j) {
- OOGLFree(edges);
- GeomDelete((Geom *)p);
- return NULL;
- }
-
- /* Call the vect create routine */
- vcounts = OOGLNewNE(short, j, msg);
- ccounts = OOGLNewNE(short, j, msg);
- verts = OOGLNewNE(Point3, j*2, msg);
- for (i = 0; i < j; i++) {
- vcounts[i] = 2;
- ccounts[i] = 0;
- Pt3Copy((const Point3 *)edges[i*2], &verts[i*2]);
- Pt3Copy((const Point3 *)edges[i*2 + 1], &verts[i*2 + 1]);
- }
- ccounts[0] = 1;
- color.r = 0.0;
- color.g = 0.0;
- color.b = 0.0;
- color.a = 1.0;
-
- vect = GeomCreate("vect",
- CR_NVECT, j,
- CR_VECTC, vcounts,
- CR_NVERT, j*2,
- CR_POINT, verts,
-
- CR_NCOLR, 1,
- CR_COLRC, ccounts,
- CR_COLOR, &color,
- CR_END);
-
- OOGLFree(ccounts);
- OOGLFree(vcounts);
- OOGLFree(edges);
-
- GeomDelete((Geom *)p);
-
- return vect;
-
- }
-
-